/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lvyh.lightframe.core.provider;

import com.lvyh.lightframe.common.ConcurrentHashSet;
import com.lvyh.lightframe.common.constant.RpcConstants;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * One provider group contains one list of some providers.
 */
public class ProviderGroup {

    /**
     * Service group name
     */
    protected final String name;

    /**
     * Server list under service grouping
     */
    protected List<ProviderInfo> providerInfoList;

    public ProviderGroup() {
        this(RpcConstants.ADDRESS_DEFAULT_GROUP, new ArrayList<ProviderInfo>());
    }

    public ProviderGroup(String name) {
        this(name, null);
    }

    public ProviderGroup(String name, List<ProviderInfo> providerInfoList) {
        this.name = name;
        this.providerInfoList = (providerInfoList == null ? new ArrayList<ProviderInfo>() : providerInfoList);
    }

    public ProviderGroup(List<ProviderInfo> providerInfoList) {
        this(RpcConstants.ADDRESS_DEFAULT_GROUP, providerInfoList);
    }

    public String getName() {
        return name;
    }

    public List<ProviderInfo> getProviderInfoList() {
        return providerInfoList;
    }

    public void setProviderInfoList(List<ProviderInfo> providerInfoList) {
        this.providerInfoList = providerInfoList;
    }

    public boolean isEmpty() {
        return CollectionUtils.isEmpty(providerInfoList);
    }

    public int size() {
        return providerInfoList == null ? 0 : providerInfoList.size();
    }

    /**
     * Add service list
     */
    public ProviderGroup add(ProviderInfo providerInfo) {
        if (providerInfo == null) {
            return this;
        }
        ConcurrentHashSet<ProviderInfo> set = new ConcurrentHashSet<ProviderInfo>(providerInfoList);
        set.add(providerInfo); // duplicate removal
        this.providerInfoList = new ArrayList<ProviderInfo>(set);
        return this;
    }

    /**
     * Add multiple service lists
     */
    public ProviderGroup addAll(Collection<ProviderInfo> providerInfoList) {
        if (CollectionUtils.isEmpty(providerInfoList)) {
            return this;
        }
        ConcurrentHashSet<ProviderInfo> tmp = new ConcurrentHashSet<ProviderInfo>(this.providerInfoList);
        tmp.addAll(providerInfoList);
        this.providerInfoList = new ArrayList<ProviderInfo>(tmp);
        return this;
    }

    /**
     * Delete service list
     */
    public ProviderGroup remove(ProviderInfo providerInfo) {
        if (providerInfo == null) {
            return this;
        }
        ConcurrentHashSet<ProviderInfo> tmp = new ConcurrentHashSet<ProviderInfo>(providerInfoList);
        tmp.remove(providerInfo);
        this.providerInfoList = new ArrayList<ProviderInfo>(tmp);
        return this;
    }

    /**
     * Delete multiple service lists
     */
    public ProviderGroup removeAll(List<ProviderInfo> providerInfoList) {
        if (CollectionUtils.isEmpty(providerInfoList)) {
            return this;
        }
        ConcurrentHashSet<ProviderInfo> tmp = new ConcurrentHashSet<ProviderInfo>(this.providerInfoList);
        tmp.removeAll(providerInfoList);
        this.providerInfoList = new ArrayList<ProviderInfo>(tmp);
        return this;
    }

    @Override
    public String toString() {
        return "ProviderGroup{" +
                "name='" + name + '\'' +
                ", providerInfoList=" + providerInfoList +
                '}';
    }

}
